<template>
  <el-input ref="elInput" v-model="moneyValue" @input="formatMoney" v-bind="$attrs" v-on="$listeners"></el-input>
</template>

<script>
/**
 * 对el-input的封装，利用@input方法限制只允许输入金钱相关内容，其余用法与el-input一致
 *
 * 新增props:{
 *   minus: 类型：Boolean 默认值：false 作用：是否启动负数金额模式，开启则允许输入负号
 * }
 */
export default {
  inheritAttrs: false,
  name: "MoneyInput",
  data() {
    return {
      moneyValue: ""
    }
  },
  props: {
    value: {},
    minus: {
      type: Boolean,
      default: false
    }
  },
  watch: {
    value: {
      handler(n) {
        this.moneyValue = this.formatMoney(n)
      },
      immediate: true
    },
  },
  methods: {
    formatMoney(moneyValue = this.moneyValue) {
      if (!moneyValue?.toString) return
      moneyValue = moneyValue.toString()
      if (this.minus) {
        moneyValue = moneyValue.replace(/[^\d.-]/g, '');
      } else {
        // 去除非数字和小数点的字符
        moneyValue = moneyValue.replace(/[^\d.]/g, '');
      }
      if (this.minus) {
        // 限制只能输入一个负号,且负号必须是字符串第一位
        const minusIndex = moneyValue.indexOf('-');
        if (minusIndex !== -1) {
          const minusCount = moneyValue.slice(minusIndex + 1).split('-').length - 1;
          if (minusCount > 0) {
            moneyValue = moneyValue.slice(0, minusIndex + 1);
          }
          if (!moneyValue.startsWith('-')) {
            moneyValue = '-' + moneyValue.replace('-', '')
          }
        }
      }
      // 限制只能输入一个小数点
      const dotIndex = moneyValue.indexOf('.');
      if (dotIndex !== -1) {
        const dotCount = moneyValue.slice(dotIndex + 1).split('.').length - 1;
        if (dotCount > 0) {
          moneyValue = moneyValue.slice(0, dotIndex + 1);
        }
      }
      // 限制只能输入两位小数
      const parts = moneyValue.split('.');
      if (parts.length > 1) {
        moneyValue = `${parts[0]}.${parts[1].slice(0, 2)}`;
      }
      this.$nextTick(() => this.$emit('input', moneyValue))
      this.$refs.elInput && this.$refs.elInput.dispatch('ElFormItem', 'el.form.change', [moneyValue])
      return moneyValue
    }
  }
}
</script>

